起因:

最近公司项目的公众号有些接口返回数据的时间很久。
原因很简单,因为是Mysql数据库而且数据量大概在500W条数据,接口响应时间在4S到5S.
体验感太差劲了。so,我们来改造下。

改造思路:

1.SQL优化。

此接口的SQL关联两张表,主订单,副产品,副货道表

  • a. 先把订单表中多加入个货道号的字段,减少一张表的关联。
  • b. 减少不需要的返回字段

这样改造后,接口返回会快一丢丢。效果不明显

2.我们直接把热点数据加入缓存中。

我们常用的缓存是 redis, mongdb 等。 但是他们都有网络开销。

我决定用本地的cache来优化。

开始是准备用项目里原来同事写的一个全局变量类的,后来想起来在极客时间看的高并发编程40问里面说的。 推荐使用google的 Google Guava 做本地缓存。

实现流程:

  1. 项目启动后,定时任务把数据塞入到缓存
  2. 从缓存中把数据拿出来返回给前端
  3. 有定时任务按时刷新缓存中的数据

不多说上代码:


import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.math.BigDecimal;

/**
 * guava本地缓存工具类
 * @author bobo
 */
public final class GuavaCacheUtil {

    private static CacheBuilder<Object, Object> cacheBuilder
            = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .initialCapacity(10)
            .recordStats();

    private static Cache<String, Object> cache;
    static {
        cache = cacheBuilder.build();
    }

    private GuavaCacheUtil() {
    }

    /**
     * 添加缓存
     *
     * @param key
     * @param value
     */
    public static void set(String key, Object value) {
        cache.put(key, value);
    }

    /**
     * 删除缓存
     *
     * @param key
     */
    public static void del(String key) {
        cache.invalidate(key);
    }

    /**
     * 根据key取得缓存对象
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        return cache.getIfPresent(key);
    }

    public static String getStr(String key) {
        return get(key).toString();
    }

    public static int getInt(String key) {
        Object value = get(key);
        if (value instanceof Integer) {
            return Integer.valueOf(value.toString());
        }
        return 0;
    }

    public static BigDecimal getBigDecimal(String key) {
        Object value = get(key);
        if (value instanceof BigDecimal) {
            return new BigDecimal(value.toString());
        }
        return BigDecimal.ZERO;
    }

    Cache<String, String> statsCache = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .initialCapacity(1000)
            .recordStats() //开启统计信息开关
            .build();
}


/** 业务中使用 **/
 @RequestMapping("getAll")
    public Object getAll(){
        List<BbaLog> bbaLogs = bbaLogMapper.findAny();
        if (bbaLogs.size()>0){
            GuavaCacheUtil.set("bba_log",bbaLogs);
            Object cacheLog = GuavaCacheUtil.get("bba_log");
            List<BbaLog> bbaLogList = (List<BbaLog>) cacheLog;
            for (BbaLog bbaLog : bbaLogList){
                System.err.println(bbaLog.getId());
            }
            return bbaLogList;
        }else {
            return "没数据";
        }
    }

其实和别的Cache差不多。但是性能比他们高很多,我只是简单的使用。 现在改造后,接口响应是1.99s,返回8000条数据。 但是实际接口数据的返回是87ms,但是8000数据Content Download的时间是1.90s. 优化下缓存中返回数据带分页效果,这样速度肯定会更快。 暂时还没优化完。 优化完后应该可以控制在100ms以内。


项目中还有挺多地方可以优化。 慢慢去修改吧、只要还给时间